"""
主窗口模块
整合各个GUI组件，提供完整的用户界面
"""

import sys
from typing import List, Dict, Union
from pathlib import Path
from PySide6.QtWidgets import (
    QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QSplitter,
    QMenuBar, QMenu, QStatusBar, QMessageBox, QFileDialog, QProgressDialog
)
from PySide6.QtCore import Qt, QThread, QTimer, Signal
from PySide6.QtGui import QAction, QIcon

from src.config import config
from src.utils.logger import app_logger
from src.core.license_plate_system import license_plate_system
from src.gui.components import (
    ImageDisplayWidget, ControlPanelWidget, 
    ResultsTableWidget, StatisticsDisplayWidget
)


class ProcessingThread(QThread):
    """
    处理线程类
    
    用途：
    - 在后台线程中执行图像处理
    - 避免阻塞主UI线程
    - 提供进度更新信号
    """
    
    progress_updated = Signal(int)  # 进度更新信号
    result_ready = Signal(list)     # 结果准备信号
    error_occurred = Signal(str)    # 错误信号
    
    def __init__(self, files, confidence_threshold, save_results):
        super().__init__()
        self.files = files
        self.confidence_threshold = confidence_threshold
        self.save_results = save_results
        self.results = []
    
    def run(self):
        """
        线程运行方法
        """
        try:
            # 更新置信度阈值
            license_plate_system.update_confidence_threshold(self.confidence_threshold)
            
            if isinstance(self.files, str):
                # 单文件处理
                self.progress_updated.emit(0)
                result = license_plate_system.process_image(
                    self.files, save_result=self.save_results
                )
                self.results = [result]
                self.progress_updated.emit(100)
            else:
                # 批量处理
                total_files = len(self.files)
                for i, file_path in enumerate(self.files):
                    result = license_plate_system.process_image(
                        file_path, save_result=self.save_results
                    )
                    self.results.append(result)
                    
                    # 更新进度
                    progress = int((i + 1) / total_files * 100)
                    self.progress_updated.emit(progress)
            
            self.result_ready.emit(self.results)
            
        except Exception as e:
            app_logger.error(f"处理线程错误: {e}")
            self.error_occurred.emit(str(e))


class MainWindow(QMainWindow):
    """
    主窗口类
    
    用途：
    - 整合所有GUI组件
    - 处理用户交互
    - 管理应用程序状态
    """
    
    def __init__(self):
        super().__init__()
        self.processing_thread = None
        self.setup_ui()
        self.setup_menu()
        self.setup_status_bar()
        self.setup_connections()
        self.setup_timer()
        
        app_logger.info("主窗口初始化完成")
    
    def setup_ui(self):
        """
        设置用户界面
        """
        # 从配置读取窗口设置
        app_info = config.get('app_info')
        self.setWindowTitle(app_info.get('name'))
        
        window_size = config.get('gui.window_size')
        self.resize(*window_size)
        
        min_size = config.get('gui.min_window_size')
        self.setMinimumSize(*min_size)
        
        # 创建中央组件
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        
        # 创建主布局
        main_layout = QHBoxLayout(central_widget)
        
        # 创建分割器
        splitter = QSplitter(Qt.Horizontal)
        
        # 创建左侧面板（控制和统计）
        left_panel = self._create_left_panel()
        splitter.addWidget(left_panel)
        
        # 创建右侧面板（图像显示和结果表格）
        right_panel = self._create_right_panel()
        splitter.addWidget(right_panel)
        
        # 设置分割器比例
        splitter_sizes = config.get('gui.splitter_sizes')
        splitter.setSizes(splitter_sizes)
        
        main_layout.addWidget(splitter)
    
    def _create_left_panel(self) -> QWidget:
        """
        创建左侧面板
        
        返回值：
            QWidget: 左侧面板组件
        """
        panel = QWidget()
        layout = QVBoxLayout(panel)
        
        # 控制面板
        self.control_panel = ControlPanelWidget()
        layout.addWidget(self.control_panel)
        
        # 统计显示
        self.statistics_display = StatisticsDisplayWidget()
        layout.addWidget(self.statistics_display)
        
        return panel
    
    def _create_right_panel(self) -> QWidget:
        """
        创建右侧面板
        
        返回值：
            QWidget: 右侧面板组件
        """
        panel = QWidget()
        layout = QVBoxLayout(panel)
        
        # 图像显示
        self.image_display = ImageDisplayWidget()
        layout.addWidget(self.image_display)
        
        # 结果表格
        self.results_table = ResultsTableWidget()
        layout.addWidget(self.results_table)
        
        return panel
    
    def setup_menu(self):
        """
        设置菜单栏
        """
        menubar = self.menuBar()
        
        # 文件菜单
        file_menu = menubar.addMenu("文件(&F)")
        
        # 打开图像
        open_action = QAction("打开图像(&O)", self)
        open_action.setShortcut("Ctrl+O")
        open_action.triggered.connect(self.control_panel.select_image)
        file_menu.addAction(open_action)
        
        # 批量打开
        batch_action = QAction("批量打开(&B)", self)
        batch_action.setShortcut("Ctrl+B")
        batch_action.triggered.connect(self.control_panel.select_batch)
        file_menu.addAction(batch_action)
        
        file_menu.addSeparator()
        
        # 导出结果
        export_action = QAction("导出结果(&E)", self)
        export_action.setShortcut("Ctrl+E")
        export_action.triggered.connect(self.export_results)
        file_menu.addAction(export_action)
        
        file_menu.addSeparator()
        
        # 退出
        exit_action = QAction("退出(&X)", self)
        exit_action.setShortcut("Ctrl+Q")
        exit_action.triggered.connect(self.close)
        file_menu.addAction(exit_action)
        
        # 帮助菜单
        help_menu = menubar.addMenu("帮助(&H)")
        
        # 关于
        about_action = QAction("关于(&A)", self)
        about_action.triggered.connect(self.show_about)
        help_menu.addAction(about_action)
    
    def setup_status_bar(self):
        """
        设置状态栏
        """
        self.status_bar = self.statusBar()
        self.status_bar.showMessage("就绪")
    
    def setup_connections(self):
        """
        设置信号连接
        """
        # 控制面板信号
        self.control_panel.image_selected.connect(self.on_image_selected)
        self.control_panel.batch_selected.connect(self.on_batch_selected)
        self.control_panel.process_requested.connect(self.start_processing)
        self.control_panel.confidence_changed.connect(self.on_confidence_changed)
        
        # 图像显示信号
        self.image_display.image_loaded.connect(self.on_image_loaded)
    
    def setup_timer(self):
        """
        设置定时器
        """
        # 状态栏更新定时器
        self.status_timer = QTimer()
        self.status_timer.timeout.connect(self.update_status)
        self.status_timer.start(5000)  # 每5秒更新一次
    
    def on_image_selected(self, image_path: str):
        """
        处理图像选择事件
        
        参数：
            image_path (str): 图像路径
        """
        self.image_display.load_image(image_path)
        self.results_table.clear_results()
        self.statistics_display.reset_statistics()
        self.status_bar.showMessage(f"已选择图像: {Path(image_path).name}")
    
    def on_batch_selected(self, image_paths: List[str]):
        """
        处理批量选择事件
        
        参数：
            image_paths (List[str]): 图像路径列表
        """
        self.image_display.clear_image()
        self.results_table.clear_results()
        self.statistics_display.reset_statistics()
        self.status_bar.showMessage(f"已选择 {len(image_paths)} 张图像")
    
    def on_image_loaded(self, image_path: str):
        """
        处理图像加载事件
        
        参数：
            image_path (str): 图像路径
        """
        self.status_bar.showMessage(f"图像加载完成: {Path(image_path).name}")
    
    def on_confidence_changed(self, threshold: float):
        """
        处理置信度改变事件
        
        参数：
            threshold (float): 新的置信度阈值
        """
        self.control_panel.update_system_info()
        self.status_bar.showMessage(f"置信度阈值已更新: {threshold:.2f}")
    
    def start_processing(self):
        """
        开始处理
        """
        files = self.control_panel.get_current_files()
        if not files:
            QMessageBox.warning(self, "警告", "请先选择图像文件")
            return
        
        # 获取设置
        confidence_threshold = self.control_panel.get_confidence_threshold()
        save_results = self.control_panel.get_save_results_enabled()
        
        # 创建处理线程
        self.processing_thread = ProcessingThread(
            files, confidence_threshold, save_results
        )
        
        # 连接信号
        self.processing_thread.progress_updated.connect(
            self.control_panel.update_progress
        )
        self.processing_thread.result_ready.connect(self.on_processing_complete)
        self.processing_thread.error_occurred.connect(self.on_processing_error)
        
        # 设置UI状态
        self.control_panel.set_processing_state(True)
        self.status_bar.showMessage("正在处理...")
        
        # 启动线程
        self.processing_thread.start()
        
        app_logger.info("开始处理图像")
    
    def on_processing_complete(self, results: List[Dict]):
        """
        处理完成事件
        
        参数：
            results (List[Dict]): 处理结果列表
        """
        try:
            # 更新结果表格
            self.results_table.update_results(results)
            
            # 更新统计信息
            stats = self.results_table.get_statistics()
            self.statistics_display.update_statistics(stats)
            
            # 如果是单张图像，显示结果
            if len(results) == 1:
                result = results[0]
                if result.get('success', False):
                    # 如果有结果图像，直接显示
                    result_image = result.get('result_image')
                    if result_image is not None:
                        self.image_display.display_result_image(result_image)
                    # 或者显示结果图像文件
                    elif result.get('result_image_path') and Path(result.get('result_image_path')).exists():
                        self.image_display.load_image(result.get('result_image_path'))
            
            # 恢复UI状态
            self.control_panel.set_processing_state(False)
            
            # 更新状态栏
            total_count = len(results)
            success_count = sum(1 for r in results if r.get('success', False))
            self.status_bar.showMessage(
                f"处理完成: {success_count}/{total_count} 成功"
            )
            
            app_logger.info(f"处理完成: {success_count}/{total_count} 成功")
            
        except Exception as e:
            app_logger.error(f"处理完成事件错误: {e}")
            self.on_processing_error(str(e))
    
    def on_processing_error(self, error_message: str):
        """
        处理错误事件
        
        参数：
            error_message (str): 错误信息
        """
        self.control_panel.set_processing_state(False)
        self.status_bar.showMessage("处理失败")
        
        QMessageBox.critical(self, "错误", f"处理失败:\n{error_message}")
        app_logger.error(f"处理失败: {error_message}")
    
    def export_results(self):
        """
        导出结果
        """
        if self.results_table.table.rowCount() == 0:
            QMessageBox.information(self, "提示", "没有可导出的结果")
            return
        
        file_path, _ = QFileDialog.getSaveFileName(
            self, "导出结果", "results.csv", "CSV文件 (*.csv)"
        )
        
        if file_path:
            success = self.results_table.export_to_csv(file_path)
            if success:
                QMessageBox.information(self, "成功", f"结果已导出到:\n{file_path}")
            else:
                QMessageBox.warning(self, "失败", "导出失败，请检查文件路径")
    
    def show_about(self):
        """
        显示关于对话框
        """
        app_info = config.get('app_info')
        about_text = f"""
{app_info.get('name')}
版本: {app_info.get('version')}

{app_info.get('description')}

开发团队: {app_info.get('organization')}
"""
        QMessageBox.about(self, "关于", about_text)
    
    def update_status(self):
        """
        更新状态栏
        """
        if not self.processing_thread or not self.processing_thread.isRunning():
            # 显示系统信息
            try:
                info = license_plate_system.get_system_info()
                status_text = f"就绪 | 置信度: {info.get('confidence_threshold', 0):.2f}"
                self.status_bar.showMessage(status_text)
            except:
                self.status_bar.showMessage("就绪")
    
    def closeEvent(self, event):
        """
        关闭事件处理
        
        参数：
            event: 关闭事件
        """
        # 如果有处理线程在运行，先停止
        if self.processing_thread and self.processing_thread.isRunning():
            reply = QMessageBox.question(
                self, "确认", "正在处理中，确定要退出吗？",
                QMessageBox.Yes | QMessageBox.No
            )
            
            if reply == QMessageBox.Yes:
                self.processing_thread.terminate()
                self.processing_thread.wait()
            else:
                event.ignore()
                return
        
        app_logger.info("应用程序退出")
        event.accept() 